package com.powernode.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.powernode.constant.BusinessEnum;
import com.powernode.constant.QueueConstants;
import com.powernode.domain.*;
import com.powernode.ex.handler.BusinessException;
import com.powernode.feign.OrderCartFeign;
import com.powernode.feign.OrderMemberFeign;
import com.powernode.feign.OrderProdFeign;
import com.powernode.mapper.OrderItemMapper;
import com.powernode.mapper.OrderMapper;
import com.powernode.model.*;
import com.powernode.service.OrderItemService;
import com.powernode.service.OrderService;
import com.powernode.util.AuthUtils;
import com.powernode.vo.OrderStatusCount;
import com.powernode.vo.OrderVo;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService{

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderItemMapper orderItemMapper;

    @Autowired
    private OrderMemberFeign orderMemberFeign;

    @Autowired
    private OrderProdFeign orderProdFeign;

    @Autowired
    private OrderCartFeign orderCartFeign;

    @Autowired
    private Snowflake snowflake;

    @Autowired
    private OrderItemService orderItemService;

    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public Page<Order> queryOrderDetailPage(Page<Order> page, Order order) {
        // 多条件分页查询订单
        page = orderMapper.selectPage(page,new LambdaQueryWrapper<Order>()
                .eq(ObjectUtil.isNotNull(order.getStatus()),Order::getStatus,order.getStatus())
                .eq(StringUtils.hasText(order.getOrderNumber()),Order::getOrderNumber,order.getOrderNumber())
                .between(StringUtils.hasText(order.getStartTime())&&StringUtils.hasText(order.getEndTime()),Order::getCreateTime,order.getStartTime(),order.getEndTime())
                .orderByDesc(Order::getCreateTime)
        );
        // 从订单分页对象中获取订单记录
        List<Order> orderList = page.getRecords();
        // 判断是否有值
        if (CollectionUtils.isEmpty(orderList) || orderList.size() == 0) {
            return page;
        }
        // 从订单记录集合中获取订单编号集合
        List<String> orderNumberList = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        // 根据订单编号查询订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .in(OrderItem::getOrderNumber, orderNumberList)
        );

        // 循环遍历订单记录集合
        orderList.forEach(order1 -> {
            // 从订单商品条目对象集合中过滤出与当前订单记录的订单编号一致的商品条目对象集合
            List<OrderItem> itemList = orderItemList.stream()
                    .filter(orderItem -> orderItem.getOrderNumber().equals(order1.getOrderNumber()))
                    .collect(Collectors.toList());
            order1.setOrderItems(itemList);
        });
        return page;
    }

    @Override
    public Order queryOrderDetailByOrderNumber(Long orderNumber) {
        // 根据订单编号查询订单信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)
        );
        // 根据订单编号查询订单的商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderNumber, orderNumber)
        );
        // 远程调用：根据订单的收货地址标识查询收货地址详情
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(order.getAddrOrderId());
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException(BusinessEnum.OPERATION_FAIL.getDesc());
        }
        // 获取收货地址对象
        MemberAddr memberAddr = result.getData();
        order.setUserAddrOrder(memberAddr);
        order.setOrderItems(orderItemList);

        // 获取买家的openid
        String openId = order.getOpenId();
        // 远程调用：根据买家的openid查询买家昵称
        Result<String> stringResult = orderMemberFeign.getMemberNickNameByOpenId(openId);
        if (stringResult.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException(BusinessEnum.OPERATION_FAIL.getDesc());
        }
        // 获取买家昵称
        String nickName = stringResult.getData();
        order.setNickName(nickName);
        return order;
    }

    ////////////////////////////////// 微信 小程序 ///////////////////////////////

    @Override
    public Order getByOrderNumber(String orderNumber) {
        return orderMapper.selectOne(new LambdaQueryWrapper<Order>().eq(Order::getOrderNumber, orderNumber));
    }

    @Override
    public OrderStatusCount queryUserOrderStatusCount(String openId) {
        // 查询用户订单待支付数量
        Long unPay = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 1)
        );
        // 查询用户订单待发货数量
        Long payed = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 2)
        );
        // 查询用户订单待收货数量
        Long consignment = orderMapper.selectCount(new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId, openId)
                .eq(Order::getStatus, 3)
        );
        return OrderStatusCount.builder()
                .unPay(Integer.valueOf(unPay.toString()))
                .payed(Integer.valueOf(payed.toString()))
                .consignment(Integer.valueOf(consignment.toString()))
                .build();
    }

    @Override
    public Page<Order> queryMemberOrderPageByStatus(Page<Order> page, Integer status) {
        // 获取当前用户的openid
        String openId = AuthUtils.getLoginUserOpenId();
        // 根据订单状态分页查询用户订单列表
        page = orderMapper.selectPage(page,new LambdaQueryWrapper<Order>()
                .eq(Order::getOpenId,openId)
                .eq(0!=status,Order::getStatus,status)
                        .eq(Order::getDeleteStatus,0)
                .orderByDesc(Order::getCreateTime)
        );
        // 从分页对象中获取订单记录
        List<Order> orderList = page.getRecords();
        // 判断是否有值
        if (CollectionUtils.isEmpty(orderList) || orderList.size() == 0) {
            return page;
        }
        // 从订单记录集合中获取订单编号
        List<String> orderNumberList = orderList.stream().map(Order::getOrderNumber).collect(Collectors.toList());
        // 根据订单编号查询订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .in(OrderItem::getOrderNumber, orderNumberList)
        );
        // 获取每一笔订单所包含的订单商品条目对象集合
        // 循环遍历订单集合
        orderList.forEach(order -> {
            // 从订单商品条目对象集合中过滤出与当前订单记录的订单编号一致的商品条目对象集合
            List<OrderItem> orderItems = orderItemList.stream()
                    .filter(orderItem -> orderItem.getOrderNumber().equals(order.getOrderNumber()))
                    .collect(Collectors.toList());
            order.setOrderItemDtos(orderItems);
        });
        return page;
    }

    @Override
    public Order queryMemberOrderDetailByOrderNumber(String orderNumber) {
        // 根据订单编号查询订单信息
        Order order = orderMapper.selectOne(new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber, orderNumber)
        );

        // 根据订单编号查询订单商品条目对象集合
        List<OrderItem> orderItemList = orderItemMapper.selectList(new LambdaQueryWrapper<OrderItem>()
                .eq(OrderItem::getOrderNumber, orderNumber)
        );
        order.setOrderItemDtos(orderItemList);

        // 远程接口调用：根据订单收货地址标识查询收货地址详情
        Result<MemberAddr> result = orderMemberFeign.getMemberAddrById(order.getAddrOrderId());
        if (result.getCode().equals(BusinessEnum.OPERATION_FAIL.getCode())) {
            throw new BusinessException(BusinessEnum.OPERATION_FAIL.getDesc());
        }
        // 获取收货地址
        MemberAddr memberAddr = result.getData();
        order.setUserAddrDto(memberAddr);

        return order;
    }

    @Override
    public Boolean cancelMemberOrderByOrderNumber(String orderNumber) {
        Order order = new Order();
        order.setStatus(6);
        order.setUpdateTime(new Date());
        order.setCancelTime(new Date());
        order.setCloseType(4);
        return orderMapper.update(order,new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber,orderNumber)
        )>0;
    }

    @Override
    public Boolean removeOrderByOrderNumber(String orderNumber) {
        Order order = new Order();
        order.setUpdateTime(new Date());
        order.setDeleteStatus(2);
        return orderMapper.update(order,new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber,orderNumber)
        )>0;
    }

    @Override
    public Boolean receiptMemberOrder(String orderNumber) {
        Order order = new Order();
        order.setUpdateTime(new Date());
        order.setFinallyTime(new Date());
        order.setStatus(5);
        return orderMapper.update(order,new LambdaQueryWrapper<Order>()
                .eq(Order::getOrderNumber,orderNumber)
        )>0;
    }

    @Override
    public OrderVo queryMemberOrderVo(OrderConfirmParam orderConfirmParam) {
        OrderVo orderVo = new OrderVo();
        // 获取会员openid
        String openId = AuthUtils.getLoginUserOpenId();
        // 远程调用：查询当前会员默认收货地址
        Result<MemberAddr> result = orderMemberFeign.getMemberDefaultAddrByOpenId(openId, orderConfirmParam.getAddrId());
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("查询当前会员默认收货地址失败");
        }
        MemberAddr memberAddr = result.getData();
        if (ObjectUtil.isNotNull(memberAddr)) {
            orderVo.setMemberAddr(memberAddr);
        }

        // 判断当前请求来自于哪里？购物车页面或商品详情页面
        // 如何判断呢？可以根据请求参数来判断
        // 获取订单确认页面请求参数对象中的购物车id集合
        List<Long> basketIds = orderConfirmParam.getBasketIds();
        if (CollectionUtils.isEmpty(basketIds) || basketIds.size() == 0) {
            // 请求来自于商品详情页面
            productToConfirm(orderConfirmParam.getOrderItem(),orderVo);
        } else {
            // 请求来自于商品购物车页面
            cartToConfirm(basketIds,orderVo);
            orderVo.setSource(1);
        }
        return orderVo;
    }



    /**
     * 处理请求来自于商品购物车页面
     * @param basketIds
     * @param orderVo
     */
    private void cartToConfirm(List<Long> basketIds, OrderVo orderVo) {
        // 远程调用：根据购物车id集合查询购物车记录
        Result<List<Basket>> result = orderCartFeign.getBasketListByIds(basketIds);
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("调用失败：根据购物车id集合查询购物车记录");
        }
        // 获取数据
        List<Basket> basketList = result.getData();
        // 从购物车记录中获取商品skuId集合
        List<Long> skuIdList = basketList.stream().map(Basket::getSkuId).collect(Collectors.toList());
        // 远程调用：根据商品skuId集合查询商品sku对象集合
        Result<List<Sku>> listResult = orderProdFeign.getSkuListBySkuIds(skuIdList);
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(listResult.getCode())) {
            throw new BusinessException("调用失败：根据商品skuId集合查询商品sku对象集合");
        }
        // 获取数据
        List<Sku> skuList = listResult.getData();

        /*以下是购物车记录集合List
        ------------------------------------
        shopId	basketId  skuId	 prodId
        ------------------------------------
        1	  1	   25	  10
        1	  2	   23	  11
        2	  3	   22	  14
        ----------------------------------------
        将购物车记录集合根据shopId进行分组,可以分为2组：店铺1和店铺2
        ------------------------------------
        key:shopId  value:购物车集合
        ------------------------------------
        店铺1包含：1和2 购物车记录
        店铺2包含：3 购物车记录*/

        // 将购物车记录集合根据店铺标识进行分组
        Map<Long, List<Basket>> allShopOrderMap = basketList.stream().collect(Collectors.groupingBy(Basket::getShopId));
        // 所有单个商品总金额
        List<BigDecimal> oneSkuTotalAmounts = new ArrayList<>();
        // 所有单个商品数量
        List<Integer> oneSkuTotalCounts = new ArrayList<>();
        // 创建订单店铺对象集合
        List<ShopOrder> shopOrderList = new ArrayList<>();
        // 循环遍历map集合
        allShopOrderMap.forEach((shopId,baskets) -> {
            // 创建订单店铺对象
            ShopOrder shopOrder = new ShopOrder();
            // 创建订单商品条目对象集合
            List<OrderItem> orderItemList = new ArrayList<>();
            // 循环当前店铺的所有购物车记录
            for (Basket basket : baskets) {
                Integer prodCount = basket.getProdCount();
                oneSkuTotalCounts.add(prodCount);
                Long skuId = basket.getSkuId();
                // 创建订单商品条目对象
                OrderItem orderItem = new OrderItem();

                orderItem.setShopId(shopId);
                orderItem.setProdCount(prodCount);
                orderItem.setCreateTime(new Date());
                orderItem.setCommSts(0);
                // 从商品sku对象集合中过滤出与当前购物车记录skuId一致的商品sku对象
                Sku sku1 = skuList.stream()
                        .filter(sku -> sku.getSkuId().equals(skuId))
                        .collect(Collectors.toList()).get(0);
                // 将商品sku1对象的属性值copy到订单商品条目对象中去
                BeanUtils.copyProperties(sku1,orderItem);
                // 计算单个商品总金额
                BigDecimal oneSkuTotalAmount = sku1.getPrice().multiply(new BigDecimal(prodCount));
                oneSkuTotalAmounts.add(oneSkuTotalAmount);
                orderItem.setProductTotalAmount(oneSkuTotalAmount);

                orderItemList.add(orderItem);
            }
            shopOrder.setShopOrderItems(orderItemList);
            shopOrderList.add(shopOrder);
        });

        orderVo.setShopCartOrders(shopOrderList);
        // 计算所有商品数量
        Integer allSkuTotalCount = oneSkuTotalCounts.stream().reduce(Integer::sum).get();
        orderVo.setTotalCount(allSkuTotalCount);
        // 计算所有单个商品总金额的和
        BigDecimal allSkuTotalAmount = oneSkuTotalAmounts.stream().reduce(BigDecimal::add).get();
        orderVo.setTotal(allSkuTotalAmount);
        orderVo.setActualTotal(allSkuTotalAmount);
        // 计算运费，如果商品总额超过99元免运费，否则运费9元
        if (allSkuTotalAmount.compareTo(new BigDecimal(99)) == -1) {
            orderVo.setTransfee(new BigDecimal(9));
            orderVo.setActualTotal(allSkuTotalAmount.add(new BigDecimal(9)));
        }
    }

    /**
     * 处理请求来自于商品详情页面
     * @param orderItem
     * @param orderVo
     */
    private void productToConfirm(OrderItem orderItem, OrderVo orderVo) {
        // 创建订单店铺对象集合
        List<ShopOrder> shopOrders = new ArrayList<>();
        // 创建订单店铺对象
        ShopOrder shopOrder = new ShopOrder();
        // 创建订单商品条目对象集合
        List<OrderItem> orderItemList = new ArrayList<>();
        // 订单商品条目对象集合
        // 购买商品数量
        Integer prodCount = orderItem.getProdCount();
        // 获取商品skuId
        Long skuId = orderItem.getSkuId();
        // 远程调用：根据商品skuId查询商品sku对象
        Result<List<Sku>> result = orderProdFeign.getSkuListBySkuIds(Arrays.asList(skuId));
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("根据商品skuId查询商品sku对象,调用失败");
        }
        List<Sku> skuList = result.getData();
        if (CollectionUtils.isEmpty(skuList) || skuList.size() == 0) {
            return ;
        }
        Sku sku = skuList.get(0);
        // 计算单个商品总金额
        BigDecimal oneSkuTotalAmount = sku.getPrice().multiply(new BigDecimal(prodCount));
        // 创建订单商品条目对象
        orderItem.setCreateTime(new Date());
        orderItem.setCommSts(0);
        orderItem.setProductTotalAmount(oneSkuTotalAmount);
        // 将商品sku对象的属性值copy到订单商品条目对象中
        BeanUtils.copyProperties(sku,orderItem);

        orderItemList.add(orderItem);
        shopOrder.setShopOrderItems(orderItemList);
        shopOrders.add(shopOrder);
        orderVo.setTotalCount(prodCount);
        orderVo.setTotal(oneSkuTotalAmount);
        orderVo.setShopCartOrders(shopOrders);
        orderVo.setActualTotal(oneSkuTotalAmount);
        // 计算运费，如果商品总额超过99元免运费，否则运费9元
        if (oneSkuTotalAmount.compareTo(new BigDecimal(99)) == -1) {
            orderVo.setTransfee(new BigDecimal(9));
            orderVo.setActualTotal(oneSkuTotalAmount.add(new BigDecimal(9)));
        }
    }

    /**
     * 会员提交订单：
     *  1.清除购物车中商品（前提：提交订单的请求来源是购物车页面）
     *  2.修改商品prod和sku的库存数量 -> 返回库存商品prod和sku库存数量对象
     *  3.写订单（涉及2张表：商品订单表order，商品订单条目表order_item）
     *  4.写延迟队列（消息：订单编号，商品prod和sku库存数量对象）（目的：处理会员超时未支付）
     *
     *
     * @param orderVo
     * @return
     */
    @Override
    public String submitMemberOrder(OrderVo orderVo) {
        String openId = AuthUtils.getLoginUserOpenId();
        // 获取订单请求来源
        Integer source = orderVo.getSource();
        if (1 == source) {
            // 清除购物车中商品
            clearMemberCheckedCartItem(orderVo,openId);
        }
        // 修改商品prod和sku的库存数量
        ChangeStock changeStock = changeProdAndSkuStock(orderVo);
        // 生成一个全局唯一订单编号
        String orderNumber = generateOrderNumber();
        // 写订单
        writeOrder(openId,orderNumber,orderVo);
        // 写延迟队列
        sendMsMsg(orderNumber,changeStock);
        return orderNumber;
    }




    /**
     * 使用雪花算法生成订单编号
     * @return
     */
    private String generateOrderNumber() {
        return snowflake.nextIdStr();
    }


    /**
     * 会员提交订单：1清除购物车中商品
     * @param orderVo
     * @param openId
     */
    private void clearMemberCheckedCartItem(OrderVo orderVo, String openId) {
        // 创建商品skuId集合
        List<Long> allSkuIdList = new ArrayList<>();
        // 获取订单店铺对象
        List<ShopOrder> shopOrderList = orderVo.getShopCartOrders();
        // 循环遍历订单店铺对象集合
        shopOrderList.forEach(shopOrder -> {
            // 从订单店铺对象中获取订单商品条目对象集合
            List<OrderItem> orderItemList = shopOrder.getShopOrderItems();
            // 从订单商品条目对象中获取当前店铺订单商品条目对象中商品skuId集合
            List<Long> skuIdList = orderItemList.stream().map(OrderItem::getSkuId).collect(Collectors.toList());
            allSkuIdList.addAll(skuIdList);
        });
        // 准备参数
        Map<String,Object> params = new HashMap<>();
        params.put("openId",openId);
        params.put("skuIdList",allSkuIdList);
        // 远程调用：根据会员标识和商品skuId集合删除购物车记录
        Result<Boolean> result = orderCartFeign.removeBasketByOpenIdAndSkuIds(params);
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("根据会员标识和商品skuId集合删除购物车记录：失败");
        }
        Boolean data = result.getData();
        if (!data) {
            throw new BusinessException("根据会员标识和商品skuId集合删除购物车记录：失败");
        }
    }

    /**
     * 会员提交订单：2修改商品prod和sku的库存数量
     * @param orderVo
     * @return
     */
    private ChangeStock changeProdAndSkuStock(OrderVo orderVo) {
        List<SkuChange> skuChangeList = new ArrayList<>();
        List<ProdChange> prodChangeList = new ArrayList<>();
        // 获取订单店铺对象集合
        List<ShopOrder> shopOrderList = orderVo.getShopCartOrders();
        // 循环遍历订单店铺对象集合
        shopOrderList.forEach(shopOrder -> {
            // 获取订单店铺对象的订单商品条目对象集合
            List<OrderItem> orderItemList = shopOrder.getShopOrderItems();
            // 循环订单商品条目对象集合
            orderItemList.forEach(orderItem -> {
                Long prodId = orderItem.getProdId();
                Long skuId = orderItem.getSkuId();
                Integer prodCount = orderItem.getProdCount()*-1;

                // 判断当前商品prodId是否在prodChangeList集合中出现
                List<ProdChange> oneProdChange = prodChangeList.stream()
                        .filter(prodChange -> prodChange.getProdId().equals(prodId))
                        .collect(Collectors.toList());
                if (CollectionUtils.isEmpty(oneProdChange) || oneProdChange.size() == 0) {
                    // 说明：当前商品prodId是第一次出现
                    SkuChange skuChange = new SkuChange(skuId, prodCount);
                    ProdChange prodChange = new ProdChange(prodId, prodCount);
                    skuChangeList.add(skuChange);
                    prodChangeList.add(prodChange);
                } else {
                    SkuChange skuChange = new SkuChange(skuId, prodCount);
                    skuChangeList.add(skuChange);

                    ProdChange prodChange = oneProdChange.get(0);
                    int finalCount = prodChange.getCount() + prodCount;
                    prodChange.setCount(finalCount);
                }
            });
        });
        // 组装数据
        ChangeStock changeStock = new ChangeStock(skuChangeList,prodChangeList);
        // 远程调用：修改商品prod和sku的库存数量
        Result<Boolean> result = orderProdFeign.changeProdAndSkuStock(changeStock);
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("调用失败：修改商品prod和sku的库存数量");
        }
        if (!result.getData()) {
            throw new BusinessException("调用失败：修改商品prod和sku的库存数量");
        }
        return changeStock;
    }

    /**
     * 会员提交订单-写订单（订单表和订单商品条目表）
     * @param openId
     * @param orderNumber
     * @param orderVo
     */
    private void writeOrder(String openId, String orderNumber, OrderVo orderVo) {
        // 获取订单店铺对象集合
        List<ShopOrder> shopOrderList = orderVo.getShopCartOrders();
        // 创建订单商品条目对象集合
        List<OrderItem> allOrderItemList = new ArrayList<>();
        // 循环遍历
        shopOrderList.forEach(shopOrder -> {
            List<OrderItem> orderItemList = shopOrder.getShopOrderItems();
            // 循环遍历店铺中的订单商品条目对象集合
            orderItemList.forEach(orderItem -> {
                orderItem.setOrderNumber(orderNumber);
                allOrderItemList.add(orderItem);
            });
        });
        // 批量添加订单商品条目对象集合
        orderItemService.saveBatch(allOrderItemList);

        // 写订单
        Order order = new Order();
        order.setOpenId(openId);
        order.setOrderNumber(orderNumber);
        order.setTotalMoney(orderVo.getTotal());
        order.setActualTotal(orderVo.getActualTotal());
        order.setRemarks(orderVo.getRemark());
        order.setStatus(1);
        order.setFreightAmount(orderVo.getTransfee());
        order.setAddrOrderId(orderVo.getMemberAddr().getAddrId());
        order.setProductNums(orderVo.getTotalCount());
        order.setCreateTime(new Date());
        order.setUpdateTime(new Date());
        order.setDeleteStatus(0);
        order.setRefundSts(0);
        order.setIsPayed(0);
        order.setReduceAmount(orderVo.getShopReduce());
        orderMapper.insert(order);
    }

    /**
     * 会员提交订单-写延迟队列
     * @param orderNumber
     * @param changeStock
     */
    private void sendMsMsg(String orderNumber, ChangeStock changeStock) {
        // 将数据存放到json对象中
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("orderNumber",orderNumber);
        jsonObject.put("changeStock",changeStock);
        rabbitTemplate.convertAndSend(QueueConstants.ORDER_MS_QUEUE,jsonObject.toJSONString());
    }

    /**
     * 订单回滚-订单超时未支付
     * @param order
     * @param changeStock
     */
    @Override
    public void orderRollBack(Order order, ChangeStock changeStock) {
        // 修改订单状态
        order.setStatus(6);
        order.setUpdateTime(new Date());
        order.setFinallyTime(new Date());
        order.setCloseType(1);
        orderMapper.updateById(order);
        // 回滚商品prod和sku的库存数量
        List<ProdChange> prodChangeList = changeStock.getProdChangeList();
        prodChangeList.forEach(prodChange -> prodChange.setCount(prodChange.getCount()*-1));
        List<SkuChange> skuChangeList = changeStock.getSkuChangeList();
        skuChangeList.forEach(skuChange -> skuChange.setCount(skuChange.getCount()*-1));
        Result<Boolean> result = orderProdFeign.changeProdAndSkuStock(changeStock);
        if (BusinessEnum.OPERATION_FAIL.getCode().equals(result.getCode())) {
            throw new BusinessException("回滚失败");
        }
    }
}
